using Sandia.MVCFramework.Plugin;
using System;
using System.Collections.Generic;
using System.Text;

namespace Sandia.MVCFramework.Common
{
    /// <summary>
    /// 
    /// </summary>
    public class PluginTools
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="availablePlugins"></param>
        /// <param name="selectedPlugins"></param>
        /// <returns></returns>
        public static Queue<IPlugin> ScheduleDependencyLoading(
            Dictionary<string, IPlugin> availablePlugins,
            Stack<string> selectedPlugins)
        {
            if (availablePlugins.Count == 0 || selectedPlugins.Count == 0)
            {
                return new Queue<IPlugin>();
            }
            Queue<IPlugin> schedule = new Queue<IPlugin>();
            string pluginIDToStart = selectedPlugins.Pop();
            if (availablePlugins.ContainsKey(pluginIDToStart))
            {
                IPlugin pluginToStart = availablePlugins[pluginIDToStart];
                // Base case...
                if (pluginToStart.Dependencies.Count == 0)
                {
                    schedule.Enqueue(pluginToStart);
                }
                else
                {
                    // Process all of this plugin's dependencies...
                    foreach (IPlugin dependency in ScheduleDependencyLoading(availablePlugins, new Stack<string>(pluginToStart.Dependencies)))
                    {
                        if (!schedule.Contains(dependency))
                        {
                            schedule.Enqueue(dependency);
                        }
                    }
                    // Now add the plugin...
                    schedule.Enqueue(pluginToStart);
                }
            }
            else
            {
                // Plugin missing...

                // Generate a log entry
                LoggingTools.SendToLog(
                    "ScheduleDependencyLoading: Plugin " + pluginIDToStart + " is missing.",
                    LoggingCategories.GENERAL,
                    50);
            }
            // Now process any remaining plugins
            if (selectedPlugins.Count != 0)
            {
                foreach (IPlugin dependency in ScheduleDependencyLoading(availablePlugins, selectedPlugins))
                {
                    if (!schedule.Contains(dependency))
                    {
                        schedule.Enqueue(dependency);
                    }
                }
            }
            // Now return...
            return schedule;
        }
    }
}
